//package com.lonely.framework.interceptor;
//
//import cn.hutool.core.collection.CollectionUtil;
//import com.alibaba.fastjson2.JSON;
//import com.alibaba.fastjson2.JSONObject;
//import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
//import com.lonely.common.core.domain.auth.LoginUser;
//import com.lonely.common.utils.spring.SpringUtils;
//import com.lonely.framework.web.service.TokenService;
//import net.sf.jsqlparser.JSQLParserException;
//import net.sf.jsqlparser.expression.Expression;
//import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
//import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
//import net.sf.jsqlparser.parser.CCJSqlParserUtil;
//import net.sf.jsqlparser.statement.select.*;
//import net.sf.jsqlparser.util.TablesNamesFinder;
//import org.apache.commons.lang3.ObjectUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.session.ResultHandler;
//import org.apache.ibatis.session.RowBounds;
//import org.springframework.beans.factory.annotation.Autowired;
//
//import javax.servlet.http.HttpServletRequest;
//import java.lang.reflect.Field;
//import java.util.Collection;
//import java.util.List;
//import java.util.Objects;
//import java.util.Set;
//
///**
// * @author kbplus
// * @version v1.0
// * @date 2022-05-13 17:49:18
// */
//public class DataPermissionInterceptor implements InnerInterceptor {
//
//    @Autowired
//    private TokenService tokenService;
//
//    @Autowired
//    private HttpServletRequest httpServletRequest;
//
//    @Override
//    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql){
//        String firstSql = boundSql.getSql();
//        Field field = null;
//        try {
//
//            Select statement = (Select) CCJSqlParserUtil.parse(boundSql.getSql());
//            if(!ifPage(parameter)){
//                return;
//            }
//
//            LoginUser loginUser = tokenService.getLoginUser(httpServletRequest);
//            if(loginUser==null){
//                return;
//            }
//
//            if(loginUser.getUser().isAdmin()){
//                return;
//            }
//
//            Set<String> dataPermissions = loginUser.getDataPermissions();
//            Set<Role> roles = loginUser.getRoles();
//            for (Role role : roles) {
//                if("admin".equals(role.getCode())){
//                    return;
//                }
//            }
//
//
//            List<String> mainTables = getMainTable(statement);
//            field = boundSql.getClass().getDeclaredField("sql");
//            field.setAccessible(true);
//
//            if(dataPermissions==null || dataPermissions.contains(DataPermissionEnum.NONE.getCode())){
//                String newSql = addWhereCondition(boundSql.getSql(), "1=2",DataPermissionEnum.NONE);
//                //通过反射修改sql语句
//                field.set(boundSql, newSql);
//                System.out.println(newSql);
//                return;
//            }
//
//            //获取公共mapper取字段是否存在
//            CommonMapper commonMapper = SpringUtils.getBean(CommonMapper.class);
//
//            String tenantTable = getFirstTableOnField("tenant_id", mainTables,commonMapper);
//            if(tenantTable!=null) {
//                //初始默认匹配租户id查询
//                String tenantSql = addWhereCondition(boundSql.getSql(), tenantTable + ".tenant_id=" + loginUser.getTenantId(), DataPermissionEnum.NONE);
//                //通过反射修改sql语句
//                field.set(boundSql, tenantSql);
//                System.out.println(tenantSql);
//            }
//
//            String organizationTable=null;
//            if(dataPermissions.contains(DataPermissionEnum.DEPT.getCode())){
//
//                organizationTable = getFirstTableOnField("create_user_organization_id", mainTables,commonMapper);
//                if(organizationTable!=null) {
//                    String newSql = addWhereCondition(boundSql.getSql(), organizationTable + ".create_user_organization_id=" + loginUser.getDeptId(), DataPermissionEnum.DEPT);
//                    //通过反射修改sql语句
//                    field.set(boundSql, newSql);
//                    System.out.println(newSql);
//                }
//            }
//
//            if(dataPermissions.contains(DataPermissionEnum.DEPT_CHILDREN.getCode())){
//
//                if(organizationTable==null){
//                    organizationTable = getFirstTableOnField("create_user_organization_id", mainTables,commonMapper);
//                }
//                if(organizationTable!=null) {
//
//                    String newSql = addWhereCondition(boundSql.getSql(), getCondition(organizationTable, "create_user_organization_id", loginUser.getDeptChildren()), DataPermissionEnum.DEPT_CHILDREN);
//                    //通过反射修改sql语句
//                    field.set(boundSql, newSql);
//                    System.out.println(newSql);
//                }
//            }
//
//            if(dataPermissions.contains(DataPermissionEnum.POST.getCode())){
//
//                String postTable = getFirstTableOnField("tenant_id", mainTables,commonMapper);
//                if(postTable!=null) {
//
//                    String sql = boundSql.getSql();
//                    if (sql.contains("where") || sql.contains("WHERE")) {
//                        sql = sql + " and ";
//                    } else {
//                        sql = sql + " where ";
//                    }
//                    String newSql = sql + getPositionCondition(postTable, "create_user_post_id", loginUser.getPostIds());
//                    //通过反射修改sql语句
//                    field.set(boundSql, newSql);
//                    System.out.println(newSql);
//                }
//            }
//            if(dataPermissions.contains(DataPermissionEnum.OWN.getCode())){
//
//                String userTable = getFirstTableOnField("create_user", mainTables,commonMapper);
//                if(userTable!=null) {
//                    String newSql = addWhereCondition(boundSql.getSql(), userTable + ".create_user=" + loginUser.getUserId(), DataPermissionEnum.OWN);
//                    //通过反射修改sql语句
//                    field.set(boundSql, newSql);
//                    System.out.println(newSql);
//                }
//            }
//        } catch (JSQLParserException | NoSuchFieldException | IllegalAccessException e) {
//            if(StringUtils.isNotEmpty(firstSql)&& ObjectUtils.isNotEmpty(field)){
//                try {
//                    field.set(boundSql, firstSql);
//                } catch (IllegalAccessException illegalAccessException) {
//                    illegalAccessException.printStackTrace();
//                }
//            }
//            e.printStackTrace();
//        }
//
//    }
//
//    /**
//     * 获取拥有字段的指定第一张表
//     *
//     * @param field
//     * @return
//     */
//    private String getFirstTableOnField(String field,List<String> tables,CommonMapper commonMapper) {
//        if(CollectionUtil.isEmpty(tables))
//            return null;
//        for (String table : tables) {
//            if(commonMapper.getFieldExists(table,field)>0)
//                return table;
//        }
//
//        return null;
//    }
//
//    /**
//     * 获取查询字段
//     *
//     * @param selectBody
//     * @return
//     */
//    private List<SelectItem> getSelectItems(SelectBody selectBody) {
//        if (selectBody instanceof PlainSelect) {
//            return ((PlainSelect) selectBody).getSelectItems();
//        }
//        return null;
//    }
//
//    /**
//     * 特殊处理 创建职业sql
//     *
//     * @param tableName 表名
//     * @param fieldName 字段名
//     * @param ids       值
//     * @return
//     */
//    private String getPositionCondition(String tableName, String fieldName, Collection<String> ids) {
//
//        StringBuilder stringBuilder = new StringBuilder();
//        stringBuilder.append("(");
//        for (String id : ids) {
//            stringBuilder.append(tableName).append(".").append(fieldName).append(" like '%").append(id).append("%' or ");
//        }
//        stringBuilder.delete(stringBuilder.length()-3,stringBuilder.length()).append(")");
//
//        return stringBuilder.toString();
//    }
//
//    /**
//     * 生成where 条件字符串
//     *
//     * @param tableName 表名
//     * @param fieldName 字段名
//     * @param ids       值
//     * @return
//     */
//    private String getCondition(String tableName, String fieldName, Collection<String> ids) {
//        return tableName + "." + fieldName + " in (" + StringUtils.join(ids, ",") + ")";
//    }
//
//    /**
//     * 获取tables的表名
//     *
//     * @param statement
//     * @return
//     */
//    private List<String> getMainTable(Select statement) {
//            TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
//            return tablesNamesFinder.getTableList(statement);
//
//    }
//
//    /**
//     * 判断是否分页
//     *
//     * @param selectBody
//     * @return
//     */
//    private Limit ifPage(SelectBody selectBody) {
//        if (selectBody instanceof PlainSelect) {
//            return ((PlainSelect) selectBody).getLimit();
//        }
//        return null;
//    }
//
//    /**
//     * 判断是否分页
//     *
//     * @param parameter
//     * @return
//     */
//    private  boolean ifPage(Object parameter) {
//        if(parameter instanceof String) return false;
//        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(parameter));
//        return jsonObject.containsKey("page") ||
//                jsonObject.containsKey("size") ||
//                jsonObject.containsKey("current");
//    }
//
//
//
//    /**
//     * 在原有的sql中增加新的where条件
//     *
//     * @param sql       原sql
//     * @param condition 新的and条件
//     * @return 新的sql
//     */
//    private String addWhereCondition(String sql, String condition, DataPermissionEnum dataPermissionEnum, List<String> detps,Set<String> posts) {
//        try {
//            Select select = (Select) CCJSqlParserUtil.parse(sql);
//            PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
//            final Expression expression = plainSelect.getWhere();
//            final Expression envCondition = CCJSqlParserUtil.parseCondExpression(condition);
//            if (Objects.isNull(expression)) {
//                plainSelect.setWhere(envCondition);
//            } else {
//                if(DataPermissionEnum.NONE==dataPermissionEnum){
//                    AndExpression andExpression = new AndExpression(expression, envCondition);
//                    plainSelect.setWhere(andExpression);
//                }else {
//                    OrExpression orExpression = new OrExpression(expression, envCondition);
//                    plainSelect.setWhere(orExpression);
//                }
//
//            }
//            return plainSelect.toString();
//        } catch (JSQLParserException e) {
//            throw new RuntimeException(e);
//        }
//    }
//
//    private String addWhereCondition(String sql, String condition, DataPermissionEnum dataPermissionEnum) {
//        return addWhereCondition(sql,condition,dataPermissionEnum,null,null);
//    }
//
//    private String addWhereCondition(String sql, String condition, DataPermissionEnum dataPermissionEnum, List<String> detps) {
//        return addWhereCondition(sql,condition,dataPermissionEnum,detps,null);
//    }
//
//    private String addWhereCondition(String sql, String condition, DataPermissionEnum dataPermissionEnum, Set<String> posts) {
//        return addWhereCondition(sql,condition,dataPermissionEnum,null,posts);
//    }
//
//}
//
